'use strict'

const expect = require('chai').expect
const AwsCompileWebsocketsEvents = require('../../../../../../../../../../lib/plugins/aws/package/compile/events/websockets/index')
const Serverless = require('../../../../../../../../../../lib/serverless')
const AwsProvider = require('../../../../../../../../../../lib/plugins/aws/provider')

describe('#compileDeployment()', () => {
  let awsCompileWebsocketsEvents

  beforeEach(() => {
    const options = {
      stage: 'dev',
      region: 'us-east-1',
    }
    const serverless = new Serverless({ commands: [], options: {} })
    serverless.setProvider('aws', new AwsProvider(serverless))
    serverless.service.provider.compiledCloudFormationTemplate = {
      Resources: {},
      Outputs: {},
    }

    awsCompileWebsocketsEvents = new AwsCompileWebsocketsEvents(
      serverless,
      options,
    )

    awsCompileWebsocketsEvents.websocketsApiLogicalId =
      awsCompileWebsocketsEvents.provider.naming.getWebsocketsApiLogicalId()
  })

  it('should create a deployment resource and output', () => {
    awsCompileWebsocketsEvents.validated = {
      events: [
        {
          functionName: 'First',
          route: '$connect',
        },
        {
          functionName: 'Second',
          route: '$disconnect',
        },
      ],
    }

    awsCompileWebsocketsEvents.compileDeployment()
    const resources =
      awsCompileWebsocketsEvents.serverless.service.provider
        .compiledCloudFormationTemplate.Resources
    const outputs =
      awsCompileWebsocketsEvents.serverless.service.provider
        .compiledCloudFormationTemplate.Outputs

    const deploymentLogicalId = Object.keys(resources)[0]

    expect(deploymentLogicalId).to.match(/WebsocketsDeployment/)
    expect(resources[deploymentLogicalId]).to.deep.equal({
      Type: 'AWS::ApiGatewayV2::Deployment',
      DependsOn: ['SconnectWebsocketsRoute', 'SdisconnectWebsocketsRoute'],
      Properties: {
        ApiId: {
          Ref: 'WebsocketsApi',
        },
        Description: 'Serverless Websockets',
      },
    })
    expect(outputs).to.deep.equal({
      ServiceEndpointWebsocket: {
        Description: 'URL of the service endpoint',
        Value: {
          'Fn::Join': [
            '',
            [
              'wss://',
              {
                Ref: 'WebsocketsApi',
              },
              '.execute-api.',
              {
                Ref: 'AWS::Region',
              },
              '.',
              {
                Ref: 'AWS::URLSuffix',
              },
              '/dev',
            ],
          ],
        },
      },
    })
  })

  it('should create a deployment resource with stage reference if websocketApiId is specified', () => {
    awsCompileWebsocketsEvents.validated = {
      events: [
        {
          functionName: 'First',
          route: '$connect',
        },
        {
          functionName: 'Second',
          route: '$disconnect',
        },
      ],
    }
    awsCompileWebsocketsEvents.serverless.service.provider.apiGateway = {
      websocketApiId: 'xyz123abc',
    }

    awsCompileWebsocketsEvents.compileDeployment()
    const resources =
      awsCompileWebsocketsEvents.serverless.service.provider
        .compiledCloudFormationTemplate.Resources

    const deploymentLogicalId = Object.keys(resources)[0]

    expect(deploymentLogicalId).to.match(/WebsocketsDeployment/)
    expect(resources[deploymentLogicalId]).to.deep.equal({
      Type: 'AWS::ApiGatewayV2::Deployment',
      DependsOn: ['SconnectWebsocketsRoute', 'SdisconnectWebsocketsRoute'],
      Properties: {
        ApiId: 'xyz123abc',
        StageName: awsCompileWebsocketsEvents.provider.getStage(),
        Description: 'Serverless Websockets',
      },
    })
  })

  it('should add deployment logical id to stage if no websocketApiId specified', async () => {
    awsCompileWebsocketsEvents.validated = {
      events: [
        {
          functionName: 'First',
          route: '$connect',
        },
        {
          functionName: 'Second',
          route: '$disconnect',
        },
      ],
    }

    return awsCompileWebsocketsEvents.compileStage().then(() => {
      awsCompileWebsocketsEvents.compileDeployment()
      const resources =
        awsCompileWebsocketsEvents.serverless.service.provider
          .compiledCloudFormationTemplate.Resources

      expect(
        resources.WebsocketsDeploymentStage.Properties.DeploymentId,
      ).to.deep.equal({
        Ref: awsCompileWebsocketsEvents.websocketsDeploymentLogicalId,
      })
    })
  })
})
